package sensor

import (
	"fmt"
	"log"
	"time"
)

// FlowParser 流速传感器解析器
type FlowParser struct {
	expectedLength int
}

func NewFlowParser(dataLength int) *FlowParser {
	return &FlowParser{
		expectedLength: dataLength, // 应该是7字节
	}
}

func (p *FlowParser) Validate(data []byte) bool {
	// 调试日志(已关闭)
	// log.Printf("流速传感器收到数据帧: % X (长度:%d)", data, len(data))

	if len(data) != p.expectedLength {
		log.Printf("流速传感器数据长度错误: 期望%d字节, 实际%d字节", p.expectedLength, len(data))
		return false
	}

	// 检查从站地址是否为0x01（根据Modbus协议）
	if data[0] != 0x01 {
		log.Printf("流速传感器从站地址错误: 期望0x01, 实际0x%X", data[0])
		return false
	}

	// 检查功能码是否为0x03（读取保持寄存器）
	if data[1] != 0x03 {
		log.Printf("流速传感器功能码错误: 期望0x03, 实际0x%X", data[1])
		return false
	}

	// 检查数据长度（第3字节应该等于数据字节数）
	dataLengthField := int(data[2])
	expectedDataBytes := len(data) - 5 // 总长度减去从站地址、功能码、数据长度字段和CRC校验码

	if dataLengthField != expectedDataBytes {
		log.Printf("流速传感器数据长度字段错误: 字段值%d, 期望%d", dataLengthField, expectedDataBytes)
		return false
	}

	// 计算CRC16校验（Modbus CRC）
	calculatedCRC := p.calculateCRC(data[:len(data)-2])
	receivedCRCLow := data[len(data)-2]
	receivedCRCHigh := data[len(data)-1]

	if calculatedCRC[0] != receivedCRCLow || calculatedCRC[1] != receivedCRCHigh {
		log.Printf("流速传感器CRC校验错误: 计算值0x%X%X, 实际值0x%X%X",
			calculatedCRC[1], calculatedCRC[0], receivedCRCHigh, receivedCRCLow)
		return false
	}

	//log.Printf("流速传感器CRC校验正确")
	return true
}

// calculateCRC 计算Modbus CRC16校验码
func (p *FlowParser) calculateCRC(data []byte) []byte {
	crc := uint16(0xFFFF)

	for _, b := range data {
		crc ^= uint16(b)
		for i := 0; i < 8; i++ {
			if crc&0x0001 != 0 {
				crc >>= 1
				crc ^= 0xA001
			} else {
				crc >>= 1
			}
		}
	}

	// 返回低位在前，高位在后的字节序列
	return []byte{byte(crc & 0xFF), byte((crc >> 8) & 0xFF)}
}

func (p *FlowParser) Parse(data []byte) (*SensorData, error) {
	if !p.Validate(data) {
		return nil, fmt.Errorf("invalid flow data format")
	}

	// 解析瞬时流量数据：第4-5字节（索引3-4），高字节在前
	flowHigh := uint16(data[3])  // 流量高字节
	flowLow := uint16(data[4])   // 流量低字节
	flowRaw := flowHigh*256 + flowLow // 放大100倍后的原始值

	// 计算实际瞬时流量：缩小100倍，单位L/min
	actualFlow := float64(flowRaw) / 100.0

	// 调试日志(已关闭)
	// log.Printf("流速传感器解析结果: 原始值=%d, 实际流量=%.2f L/min", flowRaw, actualFlow)

	return &SensorData{
		SensorType: "flow",
		Values: map[string]interface{}{
			"flow_rate":          actualFlow,        // 实际瞬时流量(L/min) - 主要数据
			"raw_flow_value":     flowRaw,           // 原始流量值(放大100倍)
			"flow_high":          data[3],           // 流量高字节
			"flow_low":           data[4],           // 流量低字节
			"slave_address":      data[0],           // 从站地址
			"function_code":      data[1],           // 功能码
			"data_length":        data[2],           // 数据长度
			"crc_low":            data[5],           // CRC校验低字节
			"crc_high":           data[6],           // CRC校验高字节
		},
		RawData:   fmt.Sprintf("%X", data),
		Timestamp: time.Now(),
	}, nil
}
